package com.kehutong.payfees.admin;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import com.kehutong.common.util.Token;
import com.kehutong.payfees.util.BasicClient;
import org.coraframework.authz.HasPermission;
import org.coraframework.converter.Converter;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.util.EnumUtil;
import org.coraframework.util.Objects;

import com.kehutong.payfees.entity.ChargeBill;
import com.kehutong.payfees.entity.ChargeGenerate;
import com.kehutong.payfees.enums.BillPaidState;
import com.kehutong.payfees.enums.CycleType;
import com.kehutong.payfees.enums.GenerateType;
import com.kehutong.payfees.enums.ResultType;

@MvcAction
@ReqMapping("/admin/charge/generate")
public class ChargeGenerateAction {

    private static final Logger logger = LoggerFactory.getLogger(ChargeGenerateAction.class);

    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private BasicClient basicClient;

    @HasPermission("charge:generate:view")
    @ReqMapping("/page")
    public Object page(Token token, JSONObject jsonObject) throws Exception {
        if(Objects.isEmpty(jsonObject.getString("communityNo"))) return new Page<>();

        Page<ChargeGenerate> page = jdbcSession.findPage(ChargeGenerate.class)
                .eq(jsonObject,  "communityNo")
                .order("createTime","desc")
                .page(jsonObject)
                .exe();

        List<ChargeGenerate> list = page.getList();

        for (int i = 0; i < list.size(); i++) {
            ChargeGenerate entity = list.get(i);

            List<String> houseNames = new ArrayList<>();
            JSONArray data = basicClient.getHouseByIds(token, entity.getHouseIds());
            if(Objects.nonNull(data)){
                data.forEach(item->{
                    JSONObject d = (JSONObject) item;
                    houseNames.add(basicClient.getHouseInfo(d));
                });
            }
            entity.setHouseNames(houseNames);
        }
        return page;
    }

    @HasPermission("charge:generate:edit")
    @ReqMapping("/save")
    public Object save(Token token, JSONObject jsonObject) throws Exception {
        ChargeGenerate generate = this.getChargeGenerate(token, jsonObject);

        jdbcSession.insert(generate);

        return Result.success();
    }

    @HasPermission("charge:generate:edit")
    @ReqMapping("/undo")
    public Object undo(Token token,String id) {
        ChargeGenerate entity = Pool.get(ChargeGenerate.class, id);

        //获取待缴费的账单信息
        List<ChargeBill> unpaidBills = jdbcSession.findArray(ChargeBill.class)
                .eq("generateNo", id)
                .eq("paidState", BillPaidState.UNPAID)
                .eq("deleted", false)
                .exe();

        // 撤销已经生成的数据
        unpaidBills.forEach(item ->{
            item.setDeleted(true);
        });
        jdbcSession.updateById(unpaidBills);

        //获取已缴费的账单信息
        List<ChargeBill> paidBills = jdbcSession.findArray(ChargeBill.class)
                .eq("generateNo", id)
                .eq("paidState", BillPaidState.PAID)
                .eq("deleted", false)
                .exe();

        // 修改状态
        entity.setResultType(ResultType.UNDO);
        jdbcSession.updateById(entity);

        StringBuilder successMsg = new StringBuilder();
        successMsg.append("执行结果：共撤销");
        successMsg.append(unpaidBills.size());
        successMsg.append("条账单，跳过已缴费的账单");
        successMsg.append(paidBills.size());
        successMsg.append("条");

        return Result.success(successMsg);
    }

    private ChargeGenerate getChargeGenerate(Token token, JSONObject jsonObject) throws Exception {

        ChargeGenerate generate = null;
        String id = jsonObject.getString("id");
        if(Objects.nonEmpty(id)){
            generate = Pool.get(ChargeGenerate.class, id);
        } else {
            generate = Pool.newInstance(ChargeGenerate.class);
        }

        generate.setOperator(token.getUsername());
        generate.setCommunityNo(jsonObject.getString("communityNo"));
        generate.setCycleType(EnumUtil.getEnum(CycleType.class, jsonObject.getString("cycleType")));
        generate.setGenerateType(EnumUtil.getEnum(GenerateType.class, jsonObject.getString("generateType")));
        generate.setExeDate(LocalDateTime.now());
        generate.setStartDate(Converter.toLocalDate(jsonObject.getString("startDate")));
        generate.setEndDate(Converter.toLocalDate(jsonObject.getString("endDate")));
        generate.setShouldPayDate(Converter.toLocalDate(jsonObject.getString("shouldPayDate")));
        generate.setResultType(ResultType.PROCESSING);
        generate.setReadMonth(jsonObject.getString("readMonth"));
        generate.setHouseIds(JSONObject.parseArray(JSONObject.toJSONString(jsonObject.getJSONArray("houseIds")), String.class));

        setDepartmentNo(generate, token.getCompanyNo());

        return generate;
    }

    private void setDepartmentNo(ChargeGenerate generate, String companyNo) throws Exception {
        JSONObject community = basicClient.getCommunityById(companyNo,
                generate.getCommunityNo());
        if(Objects.nonEmpty(community)){
            String parent_id = community.getString("parent_id");
            if(Objects.nonEmpty(parent_id)){
                generate.setDepartmentNo(parent_id);
            }
            JSONArray parent_ids = community.getJSONArray("parent_ids");
            if(Objects.nonEmpty(parent_ids)){
                List<String> departmentNos = JSONObject.parseArray(parent_ids.toJSONString(), String.class);
                generate.setDepartmentNos(departmentNos);
            }
        }
    }

}
